package top.lywivan.reggie.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.Constants;
import com.itheima.reggie.common.R;
import com.itheima.reggie.common.SecurityContext;
import com.itheima.reggie.dto.OrdersDto;
import com.itheima.reggie.entity.OrderDetail;
import com.itheima.reggie.entity.Orders;
import com.itheima.reggie.service.OrderDetailService;
import com.itheima.reggie.service.OrderService;
import com.itheima.reggie.util.AlipayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * 用户提交订单，需要填充订单表和订单明细表
     * @param orders 前端传入的订单信息
     * @return
     */
    @GetMapping("/submit")
    public void submit(Orders orders,HttpServletResponse httpResponse){
        orderService.saveWithOrderDetail(orders);
        String form = AlipayUtil.generateAlipayTradePagePayRequestForm(orders.getId() + "", "订单编号：" + orders.getId(), Double.parseDouble(orders.getAmount().toString())/100);
        try {
            httpResponse.setContentType("text/html;charset=utf-8");
            httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 当支付完成后，进行跳转页面
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/callback")
    public void callback(HttpServletRequest request,HttpServletResponse response) throws IOException {
        boolean signVerified = AlipayUtil.check(request.getParameterMap());
        if (signVerified){
            Long id = Long.parseLong(request.getParameter("out_trade_no"));
            orderService.update(Wrappers.<Orders>lambdaUpdate()
                    .set(Orders::getStatus,Constants.ORDER_STATUS_WAIT_DELIVERY)
                    .eq(Orders::getId,id));
            response.sendRedirect("http://www.lywivan.top:81/front/page/pay-success.html");
        }else {
            response.getWriter().write("验证签名失败");
        }
    }

    /**
     * 如果用户支付成功但服务器没有收到响应的情况下，进行处理
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/notify")
    public void notify(HttpServletRequest request,HttpServletResponse response) throws IOException {
        boolean signVerified = AlipayUtil.check(request.getParameterMap());
        if (signVerified){
            Long id = Long.parseLong(request.getParameter("out_trade_no"));
            orderService.update(Wrappers.<Orders>lambdaUpdate()
                    .set(Orders::getStatus,Constants.ORDER_STATUS_WAIT_DELIVERY)
                    .eq(Orders::getId,id));
            response.getWriter().write("success");
        }else {
            response.getWriter().write("验证签名失败");
        }
    }

    /**
     * 用于后端分页查询订单信息
     * @param page 当前页
     * @param pageSize 每页条数
     * @param number 查询条件：订单号
     * @param beginTime 查询条件：开始时间
     * @param endTime 查询条件：结束时间
     * @return
     */
    @GetMapping("/page")
    public R page(
            @RequestParam(required = false,defaultValue = "1")Long page,
            @RequestParam(required = false,defaultValue = "10")Long pageSize,
            String number,
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime beginTime,
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime){
        Page<Orders> ordersPage = orderService.page(new Page<Orders>(page, pageSize),
                Wrappers.<Orders>lambdaQuery()
                        .like(number != null, Orders::getNumber, number)
                        .between(beginTime != null && endTime != null, Orders::getOrderTime, beginTime, endTime)
                        .orderByDesc(Orders::getOrderTime));
        return R.success(ordersPage);
    }

    /**
     * 用于C端用户分页查询订单信息，需要包括订单明细列表，因此返回dto对象
     * @param page 当前页
     * @param pageSize 每页条数
     * @return
     */
    @GetMapping("/userPage")
    public R userPage(
            @RequestParam(required = false,defaultValue = "1")Long page,
            @RequestParam(required = false,defaultValue = "5")Long pageSize
    ){
        Page<Orders> ordersPage = orderService.page(new Page<>(page, pageSize), Wrappers.<Orders>lambdaQuery().eq(Orders::getUserId, SecurityContext.getUserId()).orderByDesc(Orders::getOrderTime));
        List<Orders> ordersList = ordersPage.getRecords();
        List<OrdersDto> ordersDtoList = ordersList.stream().map(orders -> {
            OrdersDto ordersDto = new OrdersDto();
            BeanUtils.copyProperties(orders, ordersDto);
            List<OrderDetail> orderDetailList = orderDetailService.list(Wrappers.<OrderDetail>lambdaQuery().eq(OrderDetail::getOrderId, orders.getId()));
            ordersDto.setOrderDetails(orderDetailList);
            return ordersDto;
        }).collect(Collectors.toList());
        Page<OrdersDto> ordersDtoPage = new Page<>();
        BeanUtils.copyProperties(ordersPage,ordersDtoPage);
        ordersDtoPage.setRecords(ordersDtoList);
        return R.success(ordersDtoPage);
    }

    /**
     * 修改订单的状态
     * @param orders
     * @return
     */
    @PutMapping
    public R update(@RequestBody Orders orders){
        orderService.updateById(orders);
        return R.success("订单状态修改成功");
    }

    @PostMapping("/again")
    public R again(@RequestBody Orders orders){
        orderService.saveAgain(orders);
        return R.success("再来一单成功!");
    }
}